package com.webserver.core;

import com.webserver.annotation.Controller;
import com.webserver.annotation.RequestMapping;
import com.webserver.controller.ArticleController;
import com.webserver.controller.UserController;
import com.webserver.http.HttpContext;
import com.webserver.http.HttpServletRequest;
import com.webserver.http.HttpServletResponse;

import java.io.File;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;

/**
 * 处理请求环节
 */
public class DispatcherServlet {
    //表示sources下的static目录，实际是运行时是编译后target/classes下的static目录
    private static File staticDir;
    static {
        try {
            staticDir = new File(
                    ClientHandler.class.getClassLoader().getResource(
                            "./static"
                    ).toURI()
            );
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
    }
    public void service(HttpServletRequest request, HttpServletResponse response) {
        String path = request.getRequestURI();
        System.out.println("请求路径：" + path);


        //判断该请求是否为请求某个业务
        /*
            扫描com.webserver.controller包下的所有被@Controller标注的类
            并判断那些被@RequestMapping标注的方法中，那个该注解的参数值与当前path
            值相同，那么该方法就是处理该请求的方法，利用反射机制调用即可
         */
        try {
            File  fileDirs = new File(
                     DispatcherServlet.class.getClassLoader().getResource(
                             "./com/webserver/controller"
                     ).toURI()
             );
            File[] files = fileDirs.listFiles(f -> f.getName().endsWith(".class"));
            for (int i = 0; i < files.length; i++) {
                String className = files[i].getName().substring(0, files[i].getName().indexOf("."));
                Class cls = Class.forName("com.webserver.controller."+className);
                if (cls.isAnnotationPresent(Controller.class)){
                    Method[] methods = cls.getDeclaredMethods();
                    for (int j = 0; j < methods.length; j++) {
                        if(methods[j].isAnnotationPresent(RequestMapping.class)){
                            RequestMapping mapping = methods[j].getAnnotation(RequestMapping.class);
                            String classPath = mapping.value();
                            if (classPath.equals(path)){
                                Object o = cls.newInstance();
                                methods[j].invoke(o,request,response);
                                return;
                            }
                        }
                    }

                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        //去static目录下根据用户请求的抽象路径定位下面的文件
        File file = new File(staticDir, path);
        if (file.isFile()) {//实际存在的文件
            response.setContentFile(file);

        } else {//1.文件不存在2.是一个目录
            response.setStatusCode(404);
            response.setStatusReason("NotFound");
            file = new File(staticDir, "/root/404.html");
            response.setContentFile(file);
        }

//        if ("/myweb/reg".equals(path)) {
//            UserController controller = new UserController();
//            controller.reg(request,response);
//        }
//        else {
//
//            //临时测试：将resource中static/myweb/index.html响应浏览器
//            /*
//                实际开发中，我们常用的相对路径都是类的加载路径。对应的写法:
//                类名.class.getClassLoader().getResource("./")
//                这里的"./"当前目录指的就是类加载路径的开始目录。它的实际位置
//                JVM理解的就是当前类的包名指定中最上级包的上一层。
//                例如下面的代码中，当前类ClientHandler指定的包:
//                package com.webserver.core;
//                那么包的最上级就是com，因此类加载路径的开始目录就是com的上级目录
//                实际就是项目的target/classes这个目录了。
//             */
//            //去static目录下根据用户请求的抽象路径定位下面的文件
//            File file = new File(staticDir, path);
//            if (file.isFile()) {//实际存在的文件
//                response.setContentFile(file);
//
//            } else {//1.文件不存在2.是一个目录
//                response.setStatusCode(404);
//                response.setStatusReason("NotFound");
//                file = new File(staticDir, "/root/404.html");
//                response.setContentFile(file);
//            }
//        }
    }
}
